﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpPcap;
using SharpPcap.WinPcap;
using PacketDotNet;
using System.Net;
using SharpPcap.LibPcap;
using System.IO;

namespace MyNetMonitor
{
    public partial class Form1 : Form
    {
        WinPcapDevice device = null;
        CaptureFileWriterDevice fileWriterDevice = null;
        delegate void UpdateOutput(string text);
        List<RawCapture> packetBuffer = new List<RawCapture>();
        public Form1()
        {
            InitializeComponent();
            CaptureDeviceList devices = CaptureDeviceList.Instance;
            bool found = false;
            foreach (ICaptureDevice d in devices)
            {
                if (d is WinPcapDevice)
                {
                    device = (WinPcapDevice)d;
                    found = true;
                }
            }
            if (!found)
            {
                MessageBox.Show("没有发现有线连接！");
                Application.Exit();
            }
            
        }
        void UpdateMyOutput(string text)
        {
            tbOutput.Text += text;                
        }
        void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            RawCapture packet = e.Packet;
            packetBuffer.Add(packet);
            TcpPacket tcp = TcpPacket.GetEncapsulated(Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data));
            IpPacket ip=IPv4Packet.GetEncapsulated(Packet.ParsePacket(e.Packet.LinkLayerType,e.Packet.Data));
            DateTime time = packet.Timeval.Date;
            int len = packet.Data.Length;
            string ts = String.Format("{0}:{1}:{2}:{3} Len={4} Source:{5} Dest:{6} Port:{7}\r\n", time.Hour, time.Minute, time.Second, time.Millisecond, len, ip.SourceAddress, ip.DestinationAddress, tcp.DestinationPort);
            if (fileWriterDevice != null)
            {
                fileWriterDevice.Write(packet);
            }
            tbOutput.BeginInvoke(new UpdateOutput(UpdateMyOutput), new object[] { ts });
        }
        

        private void button1_Click(object sender, EventArgs e)
        {
            packetBuffer.Clear();
            device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
            device.Open(DeviceMode.Normal, 10000);
            if (cbWrite2File.Checked)
            {
                string fileName = "LastCapture_" + tbWWW.Text + ".cap";
                if (File.Exists(fileName)) File.Delete(fileName);
                FileStream fs = File.Create(fileName);
                fs.Close(); fs.Dispose();
                fileWriterDevice = new CaptureFileWriterDevice(device, fileName);
            }
            IPHostEntry entry = Dns.GetHostEntry(tbWWW.Text);
            IPAddress[] ips = entry.AddressList;
            string filter = "net ";
            foreach (IPAddress ip in ips)
            {
                filter += ip.ToString();
                filter += " or ";
            }
            filter = filter.Substring(0, filter.Length - 3);
            filter += "and port 80";
            device.Filter = filter;
            device.StartCapture();
            MessageBox.Show("Started!");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            device.StopCapture();
            if (cbWrite2File.Checked)
            {
                fileWriterDevice.StopCapture();
                fileWriterDevice.Close();
            }
            device.Close();
            MessageBox.Show("Stopped");
        }

        private void button3_Click(object sender, EventArgs e)
        {
            tbOutput.Clear();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            device.StopCapture();
            device.Close();
        }
        public void Test1()
        {
            ushort tcpSourcePort = 123;
            ushort tcpDestinationPort = 321;
            var tcpPacket = new TcpPacket(tcpSourcePort, tcpDestinationPort);

            var ipSourceAddress = System.Net.IPAddress.Parse("192.168.1.1");
            var ipDestinationAddress = System.Net.IPAddress.Parse("192.168.1.2");
            var ipPacket = new IPv4Packet(ipSourceAddress, ipDestinationAddress);

            var sourceHwAddress = "90-90-90-90-90-90";
            var ethernetSourceHwAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(sourceHwAddress);
            var destinationHwAddress = "80-80-80-80-80-80";
            var ethernetDestinationHwAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(destinationHwAddress);

            // NOTE: using EthernetPacketType.None to illustrate that the ethernet
            //       protocol type is updated based on the packet payload that is
            //       assigned to that particular ethernet packet
            var ethernetPacket = new EthernetPacket(ethernetSourceHwAddress,
                ethernetDestinationHwAddress,
                EthernetPacketType.None);

            // Now stitch all of the packets together
            ipPacket.PayloadPacket = tcpPacket;
            ethernetPacket.PayloadPacket = ipPacket;

            // and print out the packet to see that it looks just like we wanted it to
            tbOutput.Text = ethernetPacket.ToString();

            // to retrieve the bytes that represent this newly created EthernetPacket use the Bytes property
            byte[] packetBytes = ethernetPacket.Bytes;
            foreach (byte b in packetBytes)
            {
                tbOutput.Text += b.ToString("X") + " ";
            }
        }

        private void btnResolve_Click(object sender, EventArgs e)
        {
            string name = Dns.GetHostName();
            IPHostEntry entrybaidu = Dns.GetHostEntry("www.baidu.com");
            IPHostEntry entryVen = Dns.GetHostEntry("venucia.auto.sina.com.cn");
        }

        private void button5_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Directory.GetCurrentDirectory();
            ofd.Filter = "捕捉文件|*.cap";
            DialogResult dialogResult = ofd.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                CaptureFileReaderDevice fileReaderDevice = new CaptureFileReaderDevice(ofd.FileName);
                fileReaderDevice.OnPacketArrival += new PacketArrivalEventHandler(fileReaderDevice_OnPacketArrival);
                fileReaderDevice.Capture();
            }
        }

        void fileReaderDevice_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            RawCapture packet = e.Packet;
            packetBuffer.Add(packet);            
            TcpPacket tcp = TcpPacket.GetEncapsulated(Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data));
            IpPacket ip=IPv4Packet.GetEncapsulated(Packet.ParsePacket(e.Packet.LinkLayerType,e.Packet.Data));
            DateTime time = packet.Timeval.Date;
            int len = packet.Data.Length;
            string ts = String.Format("{0}:{1}:{2}:{3} Len={4} Source:{5} Dest:{6} Port:{7}\r\n", time.Hour, time.Minute, time.Second, time.Millisecond, len, ip.SourceAddress, ip.DestinationAddress, tcp.DestinationPort);
            tbOutput.Text += ts;
        }

        private void button6_Click(object sender, EventArgs e)
        {
            AnalyzeForm analyzeForm = new AnalyzeForm(packetBuffer);
            analyzeForm.Show();
        }

    }
}
